package com.ybkj.o2o.mc.aop;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ybkj.o2o.mc.common.AesUtil;
import com.ybkj.o2o.mc.common.DateDeserializer;
import com.ybkj.o2o.mc.common.DateSerializer;
import com.ybkj.o2o.mc.common.transport.Result;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.DateFormat;

@Aspect
@Component
public class EncryptAop{
	
	
    
	@Pointcut("execution(public * com.ybkj.o2o.mc.controller.*.*.*(..))")
    public void pointCutApi() {
    	
    }

	private final static Logger logger = LoggerFactory.getLogger(EncryptAop.class);
    @Around("pointCutApi()")
    public Object pointCutApi(ProceedingJoinPoint thisJoinPoint) throws Throwable {

    	RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

    	String x_type = request.getHeader("X-type");
    	doBefore(thisJoinPoint);
    	return dataHandle(x_type,thisJoinPoint);

    }

	private void doBefore(JoinPoint joinPoint){
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		// 记录下请求内容
		String req = null;
		try{
			req = JSONObject.toJSONString(joinPoint.getArgs());
		}catch (Exception e){

		}
		logger.info("URL:{} |METHOD:{} |REQ: {} ",request.getRequestURL().toString(),request.getMethod(),req);
	}
    private Object dataHandle(String x_type,ProceedingJoinPoint thisJoinPoint) throws Throwable {

    	Object args[] = thisJoinPoint.getArgs();

//    	if(true){
    	if(StringUtils.isNotBlank(x_type) && x_type.equals("sign")){
//    		if(null!=args && args.length>0){
//        		for (int i = 0; i < args.length; i++) {
//        			Object obj = args[i];
//        			System.out.println(obj);
//        			if(null!=obj){
//        				args[i]=AesUtil.aesDecrypt(URLDecoder.decode(String.valueOf(obj), "UTF-8"), AesUtil.VIPARA);
//        			}
//            	}
//        	}

        	Object obj = thisJoinPoint.proceed(args);
			logger.info("RESPONSE : " + obj);
        	if(obj instanceof com.ybkj.o2o.mc.controller.v4.ResultTransport){
        		com.ybkj.o2o.mc.controller.v4.ResultTransport result = (com.ybkj.o2o.mc.controller.v4.ResultTransport)obj;
        		Object data = result.getData();
        		if(null!=data){
        			Gson gson = createGson();
        			result.setData(AesUtil.aesEncrypt(String.valueOf(gson.toJson(data)) , AesUtil.VIPARA));
        	        return result;
        		}
        		else{
        			return obj;
        		}
        	}
        	else if(obj instanceof Result){
        		@SuppressWarnings("unchecked")
				Result<Object> result = (Result<Object>)obj;
        		Object data = result.getData();
        		if(null!=data){
        			Gson gson = createGson();
        			String Aesdata=AesUtil.aesEncrypt(String.valueOf(gson.toJson(data)) , AesUtil.VIPARA);
        			result.setData(Aesdata);
        	        return result;
        		}
        		else{
        			return obj;
        		}
        	}
        	else{
        		return obj;
        	}
    	}
    	else{
    		Object obj = thisJoinPoint.proceed(args);
			logger.info("RESPONSE : " + obj);
    		return obj;
    	}
	}
    
    private static Gson createGson(){
    	GsonBuilder gb = new GsonBuilder();
        gb.registerTypeAdapter(java.util.Date.class, new DateSerializer()).setDateFormat(DateFormat.LONG);
        gb.registerTypeAdapter(java.util.Date.class, new DateDeserializer()).setDateFormat(DateFormat.LONG);
        Gson gson = gb.create();
        return gson;
    }

    
 }